; docformat = 'rst'
;
;+
;
; :Purpose:
;   Orientate gridded data, so that latitudes are ordered from -90 to 90, and 
;   longitudes are ordered from 0 to 360.
;
; :Inputs:
;   coord1: Array of grid cell locations. 
;     If this is the only input, it can be either longitude or latitude, but if a 0->360 longitude output
;     is required, set /longitude keyword.
;   coord2: Array of latitudes. Only to be specified if coord1 and data array are specified.
;   data: 2D field, with dimensions (coord1, coord2). 
;
; :Keywords:
;   longitude: (boolean) only to be set to true if one input parameter (coord1) is give. 
;     If true, then coord1 is a longitude, and will be ordered from 0 to 360, unless /neglon is set!
;   neglon: (boolean) set to true if longitudes should be ordered from -180 to 180
;   no_wrap: (boolean) set to true if longitudes should not be re-ordered, but should be left in place
;     and just re-labeled as positive values
;   
; :Example::
;   
;   Re-order a latitude array:
;     IDL> lat=-1.*findgen(4)
;     IDL> print, lat
;         -0.00000     -1.00000     -2.00000     -3.00000
;     IDL> mr_grid_orient, lat
;     IDL> print, lat
;         -3.00000     -2.00000     -1.00000     -0.00000
;   Re-order a longitude array:
;     IDL> lon=[-10., 0., 10., 20.]
;     IDL> print, lon
;         -90.0000      0.00000      90.0000      180.0000
;     IDL> mr_grid_orient, lon, /longitude
;     IDL> print, lon
;         0.0000000       90.000000       180.000000       270.00000
;     
;   Re-order a map:
;      IDL> lon=[-90., 0., 90., 180.]
;      IDL> lat=[10., 0., -10., -20.]
;      IDL> map=findgen(4, 4)
;      
;      IDL> print, map
;      0.00000      1.00000      2.00000      3.00000
;      4.00000      5.00000      6.00000      7.00000
;      8.00000      9.00000      10.0000      11.0000
;      12.0000      13.0000      14.0000      15.0000
;      
;      IDL> mr_grid_orient, lon, lat, map
;      
;      IDL> print, lon
;      0.0000000       90.000000       180.00000       270.00000
;      IDL> print, lat
;      -20.0000     -10.0000      0.00000      10.0000
;      IDL> print, map
;      13.000000       14.000000       15.000000       12.000000
;      9.0000000       10.000000       11.000000       8.0000000
;      5.0000000       6.0000000       7.0000000       4.0000000
;      1.0000000       2.0000000       3.0000000       0.0000000

; :History:
; 	Written by: Matt Rigby, University of Bristol, Jul 16, 2013
;
;-
pro mr_grid_orient, coord_1, coord_2, data, $
  longitude=longitude, no_wrap=no_wrap, neglon=neglon

  Case n_params() of

    ;Only an array or scalar of longitudes or latitudes are input
    1: begin

      ;Check direction
      if (keyword_set(no_wrap) eq 0) and (n_elements(coord_1) gt 1) then begin
        if (coord_1[1] lt coord_1[0]) then begin
          coord_1=reverse(coord_1)
        endif
      endif
      
      ;If longitude then check that it goes from 0 to 360 degrees
      if keyword_set(longitude) then begin

        if keyword_set(no_wrap) then begin
          wh=where(coord_1 lt 0.)
          if wh[0] ne -1 then begin
            coord_1[wh]=360. + coord_1[wh]
          endif
        endif else begin
          coord_1_temp=dblarr(n_elements(coord_1))
          wh_0_180=where(coord_1 ge 0.)
          wh_180_360=where(coord_1 lt 0.)
          if (wh_0_180[0] eq -1) or (wh_180_360[0] eq -1) then begin      
            if wh_180_360[0] ne -1 then coord_1=360. + coord_1
          endif else begin
            coord_1_temp[0:n_elements(wh_0_180)-1]=coord_1[wh_0_180]
            coord_1_temp[n_elements(wh_0_180):n_elements(coord_1)-1]=360. + coord_1[wh_180_360]
          endelse
          coord_1=coord_1_temp        
        endelse

      endif
      
    end


    ;A data array with corresponding x, y coorinates are input
    3: begin

      ;Check if anything needs to be done
      if (min(coord_1) ge 0. and ~keyword_set(neglon)) and (coord_2[1] gt coord_2[0]) then return  ;Nothing to be done
      
      ;Reverse lat if necessary
      if coord_2[1] lt coord_2[0] then begin
        coord_2=reverse(coord_2)
        data=reverse(data, 2)
      endif

      ;Re-order longitudes
      if keyword_set(neglon) eq 0 then begin
        wh_0_180=where(coord_1 ge 0.)
        wh_180_360=where(coord_1 lt 0.)
      endif else begin
        wh_0_180=where(coord_1 ge 180.)
        wh_180_360=where(coord_1 lt 180.)    
      endelse
    
      datasize=size(data)
      datatemp=dblarr(datasize[1:datasize[0]])

            
      if (wh_0_180[0] eq -1) or (wh_180_360[0] eq -1) then begin
    
        if wh_180_360[0] ne -1 then coord_1=360. + coord_1
    
      endif else begin
        
        ;Re-order data
        if ~keyword_set(no_wrap) then begin
    
          case (datasize[0]) of 
            2: begin
              datatemp[0:n_elements(wh_0_180)-1, *]=data[wh_0_180, *]
              datatemp[n_elements(wh_0_180):n_elements(coord_1)-1, *]=data[wh_180_360, *]
            end
            3: begin
              datatemp[0:n_elements(wh_0_180)-1, *, *]=data[wh_0_180, *, *]
              datatemp[n_elements(wh_0_180):n_elements(coord_1)-1, *, *]=data[wh_180_360, *, *]
            end
            4: begin
              datatemp[0:n_elements(wh_0_180)-1, *, *, *]=data[wh_0_180, *, *, *]
              datatemp[n_elements(wh_0_180):n_elements(coord_1)-1, *, *, *]=data[wh_180_360, *, *, *]
            end
            5: begin
              datatemp[0:n_elements(wh_0_180)-1, *, *, *, *]=data[wh_0_180, *, *, *, *]
              datatemp[n_elements(wh_0_180):n_elements(coord_1)-1, *, *, *, *]=data[wh_180_360, *, *, *, *]
            end
          endcase

          data=datatemp
          
          ;Re-order longitudes
          coord_1temp=dblarr(n_elements(coord_1))
          
          if keyword_set(neglon) eq 0 then begin
            coord_1temp[0:n_elements(wh_0_180)-1]=coord_1[wh_0_180]
            coord_1temp[n_elements(wh_0_180):n_elements(coord_1)-1]=360. + coord_1[wh_180_360]
          endif else begin
            coord_1temp[0:n_elements(wh_0_180)-1]=-360. + coord_1[wh_0_180]
            coord_1temp[n_elements(wh_0_180):n_elements(coord_1)-1]=coord_1[wh_180_360]
          endelse
          
          coord_1=coord_1temp

        endif else begin
          
          ;Just re-label longitudes, don't re-order
          wh=where(coord_1 lt 0.)
          if wh[0] ne -1 and ~keyword_set(neglon) then begin
            coord_1[wh]=360. + coord_1[wh]
          endif
          
        endelse
        
      endelse
      
    end
    
    else: message, "Either input coord1 alone, or input three parameters (lon, lat, data)"
    
  endcase

End